<template>
    <n-card v-if="session !== 'all-over'" :title="`${session}${half}-${$t('text.sideMapChoose')}`">
        <n-form ref="sideFormRef" :model="gameInfo" :rules size="small" label-placement="top">
            <n-grid :cols="24" :x-gap="24">
                <n-form-item-gi :span="12" :label="$t('label.survivorTeam')" path="survivorTeam">
                    <n-select :disabled="disSideSelect" v-model:value="gameInfo.survivorTeam"
                        placeholder="Select Survivor Team" :options="teamSelectionOptions"
                        @update:value="handleUpdateValue" />
                </n-form-item-gi>
                <n-form-item-gi :span="12" :label="$t('label.hunterTeam')" path="hunterTeam">
                    <n-select disabled v-model:value="gameInfo.hunterTeam" placeholder="Select Hunter Team"
                        :options="teamSelectionOptions" />
                </n-form-item-gi>
            </n-grid>
            <n-grid :cols="24" :x-gap="24">
                <n-form-item-gi :span="12" :label="$t('label.banMap')" path="banMap">
                    <n-select filterable :disabled="disSideSelect || !boInfo.banMap" v-model:value="gameInfo.banMap"
                        :render-label="renderMap" placeholder="Select A Map To Disable" :options="banMapOptions" />
                </n-form-item-gi>
                <n-form-item-gi :span="12" :label="$t('label.pickMap')" path="pickMap">
                    <n-select filterable :disabled="disSideSelect || !boInfo.chooseMap" v-model:value="gameInfo.pickMap"
                        :render-label="renderMap" placeholder="Select A Map" :options="chooseMapOptions" />
                </n-form-item-gi>
            </n-grid>
            <n-grid :cols="24" :x-gap="24" v-show="pickMapSet.size > 0">
                <n-form-item-gi :span="12" :label="$t('text.hasChooseMap')">
                    <div class="global-flex-center" style="gap:0.5em;flex-wrap: wrap;">
                        <n-tag :bordered="false" type="error" v-for="(item, index) in pickMapSet" :key="index">
                            {{ item }}
                        </n-tag>
                    </div>
                </n-form-item-gi>
            </n-grid>
            <n-grid :cols="24" :x-gap="24">
                <n-form-item-gi :span="24" :label="$t('text.hasChoosePerson')">
                    <div class="grid_person">
                        <div class="global-flex-center" style="gap:0.5em;flex-wrap: wrap;">
                            <n-tag type="info" v-for="(item, index) in teamInfo[gameInfo.survivorTeam]?.survivor ?? []"
                                :key="index">
                                <template #icon>
                                    <img src="../../assets/images/survivor.png">
                                </template>
                                {{ item || '未选边' }}
                            </n-tag>
                        </div>
                        <div class="global-flex-center">
                            <n-icon :size="22">
                                <FitnessSharp />
                            </n-icon>
                        </div>
                        <div class="global-flex-center">
                            <n-tag type="error">
                                <template #icon>
                                    <img src="../../assets/images/hunter.png">
                                </template>
                                {{ teamInfo[gameInfo.hunterTeam]?.hunter || '未选边' }}
                            </n-tag>
                        </div>
                    </div>
                </n-form-item-gi>
            </n-grid>
            <div class="footer_button" v-show="session !== 'all-over'">
                <n-button-group>
                    <n-button strong secondary type="info" :disabled="['processing', 'over'].includes(processingStatus)"
                        @click="startGame">
                        <template #icon>
                            <n-icon>
                                <GitCompareSharp />
                            </n-icon>
                        </template>
                        <!-- 开始bp -->
                        {{ $t('button.startBP') }}
                    </n-button>
                    <!-- 换边-上半场结束变成over，half变成下半，下半场结束，变成side ，half变成上半 -->
                    <n-button v-show="processingStatus === 'over' && half === '下半'" @click="handleChangeSide">
                        <template #icon>
                            <n-icon>
                                <GitCompareOutline />
                            </n-icon>
                        </template>
                        {{ $t('button.changeSide') }}
                    </n-button>
                </n-button-group>
            </div>
        </n-form>
    </n-card>
    <p class="game_over--warning" v-else>{{ $t('text.noGameWarning') }}</p>
    <n-card :title="$t('label.startBp')" v-if="processingStatus === 'processing'">
        <ProcessForm v-if="processingArray.length > 0" :process="processingArray" :gameInfo :teamInfo
            @emitScore="fillTheScore" />
        <n-result v-else status="404" title="404 无流程" description="该环节bp流程未配置！">
            <template #footer>
                <n-button @click="jumpToConfig">点击配置</n-button>
            </template>
        </n-result>
    </n-card>
    <n-card :title="$t('label.allScore')">
        <ScoreAllBoard :allScore :teamInfo />
    </n-card>
</template>

<script setup lang='ts' name="GameScheduleProcessing">
import BoardChannel from '@/utils/boardChannel';
import storeHelper from '@/utils/TauriStore';
import { useMessage, type FormInst, type SelectOption } from 'naive-ui';
import { deepClone } from '@/utils';
import { mapOptions } from '@/utils/generateImageOptions.ts';
import { GitCompareSharp, GitCompareOutline, FitnessSharp } from '@vicons/ionicons5'
import { generateProcessObject, ProcessInterface } from './generator';
import ProcessForm from './ProcessForm.vue';
import ScoreAllBoard from './ScoreAllBoard.vue';
import { useGameStore } from '@/stores/game';
import { VNodeChild } from 'vue';
import { BOConfig } from '@/common/nomalRules';

const NONECHOOSE = '无禁用';
const boInfo = ref<Omit<BOConfig, 'hunterBanNumber' | 'survivorBanNumber'>>({
    chooseMap: true,
    banMap: true,
});
const props = defineProps<{
    'session': string
}>();
const emits = defineEmits<{
    (event: 'updateSession'): void
}>();

const { stop } = watch(() => props.session, async (newVal) => {
    try {
        if (!newVal) return;
        const boStep = await storeHelper.get('use_step_config');
        if (boStep && typeof boStep === 'object') {
            boInfo.value = boStep[newVal] ?? {
                chooseMap: true,
                banMap: true,
            };
        }
        gameInfo.banMap = !boInfo.value.banMap ? NONECHOOSE : null;
        if (boInfo.value.chooseMap) {
            gameInfo.pickMap = null;
        }
    } catch (error) {
        boInfo.value = {
            chooseMap: true,
            banMap: true,
        }
    }
}, { immediate: true });
// 已选择的地图不可重复选择/禁用
const pickMapSet = reactive<Set<string>>(new Set()); // 使用 reactive 包装 Set
const mapOptionsRef = ref(mapOptions);
// 禁用地图\选取地图列表
const banMapOptions = computed(() => {
    return mapOptionsRef.value.map(item => {
        return {
            ...item,
            disabled: pickMapSet.has(item.label)
        }
    })
});
const chooseMapOptions = computed(() => {
    return mapOptionsRef.value.filter(option => option.label !== NONECHOOSE).map(item => {
        return {
            ...item,
            disabled: item.label === gameInfo.banMap || pickMapSet.has(item.label)
        }
    })
});
const gameStore = useGameStore();
const sideFormRef = ref<null | FormInst>(null);
const router = useRouter();
const message = useMessage();
const channel = new BoardChannel('bp-system');
const teamSelectionOptions = ref<SelectOption[]>([]);
const half = ref<'上半' | '下半'>('上半');
type Processing = 'side' | 'prepareSide' | 'processing' | 'over'; //选边阶段、选边结束阶段、bp阶段、结束阶段
const processingStatus = ref<Processing>('side'); //上半是否结束
const allScore = reactive<AllScore>({       // 全局计分函数
    team1: [],
    team2: []
})
// 是否禁用边情况
const disSideSelect = computed(() => {
    return processingStatus.value !== 'side'
});
const processingArray = reactive<ProcessInterface[]>([]);
// 规则
const rules = {
    survivorTeam: [{
        required: true,
        trigger: 'input',
        message: 'Pick Survivor Side'
    }],
    hunterTeam: [{
        required: true,
        trigger: 'input',
        message: 'Pick Hunter Side'
    }],
    banMap: [{
        required: true,
        trigger: 'input',
        message: 'Ban The Map'
    }],
    pickMap: [{
        required: true,
        trigger: 'input',
        message: 'Pick The Map'
    }]
}
onMounted(() => {
    _init();
    channel.on('teamInfoChange', async (bool: boolean) => {
        if (bool) {
            _init();
        }
    });
});
onUnmounted(() => {
    stop();
})
const gameInfo = reactive<GameInfo>({
    survivorTeam: 'team1', //team1 || team2
    hunterTeam: 'team2', //team1 || team2
    banMap: null,
    pickMap: null,
    team1Score: {
        win: 0,
        down: 0,
        lose: 0,
        smallScore: 0,
        gloalban: []
    },
    team2Score: {
        win: 0,
        down: 0,
        lose: 0,
        smallScore: 0,
        gloalban: []
    }
});
const teamInfo = reactive<Partial<TeamInfo>>({});

async function _init() {
    try {
        const teams = await storeHelper.get('teamInfo') as TeamInfo;
        Object.assign(teamInfo, teams);
        if (typeof teams === 'object') {
            teamSelectionOptions.value = [];
            teamSelectionOptions.value.push({
                value: 'team1',
                label: teams.team1.teamName
            });
            teamSelectionOptions.value.push({
                value: 'team2',
                label: teams.team2.teamName
            })
        };
        const allScoreObject = await storeHelper.get('allScore') as AllScore;
        if (typeof allScoreObject === 'object') {
            Object.assign(allScore, allScoreObject);
        }
    } catch (error) {
        console.log(error);
    }
};
// 更新
const handleUpdateValue = (e: string) => {
    const otherTeam = teamSelectionOptions.value.find(item => item.value !== e) ?? {};
    gameInfo.hunterTeam = otherTeam?.value as keyof TeamInfo;
};
// 开始bp
const startGame = () => {
    sideFormRef.value?.validate(async (errors) => {
        if (!errors) {
            if (half.value === '上半') {
                gameInfo[`${gameInfo.survivorTeam}Score`].smallScore = 0;
                gameInfo[`${gameInfo.hunterTeam}Score`].smallScore = 0;
            }
            try {
                updateGameInfo(false, true);
                processingArray.length = 0;
                const result = await generateProcessObject(props.session, toRaw(gameInfo), toRaw(teamInfo));
                result.forEach(process => {
                    processingArray.push(process);
                });
                // 让规则数据加载好了再渲染
                await nextTick();
                processingStatus.value = 'processing';
                channel.send('resetTime', true);
                pickMapSet.add(gameInfo.pickMap as string);
            } catch (error) {
                message.error(error instanceof Error ? error.message : '未知错误')
            }

        } else {
            message.error('请完整填写表单！');
        }
    })
}
// 结束一场登分
const fillTheScore = (score: GlobalScoreEmit) => {
    computedScoreList(score, gameInfo);
    if (half.value === '上半') {
        gameInfo[`${gameInfo.survivorTeam}Score`].smallScore = score.survivor;
        gameInfo[`${gameInfo.hunterTeam}Score`].smallScore = score.hunter;
        score.survivorBan.forEach((path: string) => {
            gameInfo[`${gameInfo.survivorTeam}Score`].gloalban.push(path);
        });
        score.hunterBan.forEach((path: string) => {
            gameInfo[`${gameInfo.hunterTeam}Score`].gloalban.push(path);
        });
        updateGameInfo(false);
    } else {
        gameInfo[`${gameInfo.survivorTeam}Score`].smallScore += score.survivor;
        gameInfo[`${gameInfo.hunterTeam}Score`].smallScore += score.hunter;
        computedBigScore();
        emits('updateSession');
        updateGameInfo(true);
    }
    gameStore.setGlobalBan(gameInfo.survivorTeam, 'survivor', score.survivorBan);
    gameStore.setGlobalBan(gameInfo.hunterTeam, 'hunter', score.hunterBan);
    processingStatus.value = half.value === '上半' ? 'over' : 'side';
    half.value = half.value === '上半' ? '下半' : '上半';
    processingArray.length = 0;
}
// 派发更新-clearbp-是否触发清除bp画面
const updateGameInfo = (clearMap: boolean, clearbp?: boolean) => {
    const cloneGameInfo = deepClone(gameInfo);
    channel.send('gameInfoChange', {
        ...cloneGameInfo,
        session: props.session
    });
    storeHelper.set('gameInfo', cloneGameInfo);
    if (clearbp) {
        channel.send('clearBp', clearMap);
    }
}
// 计算大分并销毁
const computedBigScore = () => {
    if (gameInfo[`${gameInfo.survivorTeam}Score`].smallScore === gameInfo[`${gameInfo.hunterTeam}Score`].smallScore) {
        gameInfo[`${gameInfo.survivorTeam}Score`].down++;
        gameInfo[`${gameInfo.hunterTeam}Score`].down++;
    } else if (gameInfo[`${gameInfo.survivorTeam}Score`].smallScore > gameInfo[`${gameInfo.hunterTeam}Score`].smallScore) {
        gameInfo[`${gameInfo.survivorTeam}Score`].win++;
        gameInfo[`${gameInfo.hunterTeam}Score`].lose++;
    } else {
        gameInfo[`${gameInfo.survivorTeam}Score`].lose++;
        gameInfo[`${gameInfo.hunterTeam}Score`].win++;
    }
};
// 换边逻辑
const handleChangeSide = () => {
    let middleVarable = gameInfo.survivorTeam;
    gameInfo.survivorTeam = gameInfo.hunterTeam;
    gameInfo.hunterTeam = middleVarable;
    updateGameInfo(false, true);
    processingStatus.value = 'prepareSide';
};
watch(
    () => [gameInfo.banMap, gameInfo.pickMap],
    ([banNewVal, pickNewVal]) => {
        storeHelper.set('mapSelect', {
            banMap: banNewVal,
            pickMap: pickNewVal
        });
        channel.send('mapSelect', {
            banMap: banNewVal,
            pickMap: pickNewVal
        });
    }
);

// 计份函数
const computedScoreList = (score: GlobalScoreEmit, gameInfo: GameInfo) => {
    allScore[gameInfo.survivorTeam].push(score.survivor);
    allScore[gameInfo.hunterTeam].push(score.hunter);
    storeHelper.set('allScore', allScore);
}
// 配置流程规则
const jumpToConfig = () => {
    router.push('/rule')
}

// 渲染
const renderMap = (option: SelectOption): VNodeChild => {
    const imageUrl = new URL(`../../assets/images/map/${option.value}.png`, import.meta.url).href;
    return [
        h('img', {
            src: imageUrl,
            style: {
                width: '60px', // Adjust size as needed
                height: '20px', // Adjust size as needed
                verticalAlign: 'middle',
                marginRight: '8px',
                filter: option.disabled ? 'grayscale(100%)' : 'none',
                objectFit: 'cover', // 裁剪图片，保持比例，填充整个容器
                objectPosition: 'center', // 居中裁剪
            }
        }),
        option.label as string
    ]
}
</script>
<style scoped lang='scss'>
.footer_button {
    display: flex;
    align-items: center;
    justify-content: center;
}

.grid_person {
    width: 100%;
    display: grid;
    grid-template-columns: 45% 10% 45%;

    img {
        height: 22px;
        width: 22px;
    }
}
//提示文字
.game_over--warning{
    color:#f40;
    padding:0.5em;
    font-weight: 500;
}
</style>